package com.sojson.util.encrypt.oneway.alike.md5;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.sojson.util.StringUtil;
import com.sojson.util.encrypt.EncryptUtil;
import com.sojson.util.encrypt.enums.EEncryptType;

import lombok.extern.slf4j.Slf4j;

/**
 * MD5单向加密工具类
 * 
 * @author liu
 * @date 2020-09-04
 */
@Slf4j
public class Md5Util {

    private static final MessageDigest MD = getMd5();

    /**
     * 加密
     * 
     * @param data
     * @return
     */
    public static String encrypt(String data) {
        return encryptToStr(data.getBytes());
    }

    /**
     * 加密
     * 
     * @param data
     * @return
     */
    public static byte[] encrypt(byte[] data) {
        return encryptToStr(data).getBytes();
    }

    /**
     * 加密
     * 
     * @param data
     * @return
     */
    public static String encryptToStr(byte[] data) {
        byte[] array = MD.digest(data);
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    }

    /**
     * 加密
     * 
     * @param data
     * @return
     */
    public static byte[] encryptToByte(String data) {
        return encrypt(data.getBytes());
    }

    /**
     * 加密
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static String encrypt(String data, String key) {
        return encryptToStr(data.getBytes(), key);
    }

    /**
     * 加密
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static byte[] encrypt(byte[] data, String key) {
        return encryptToStr(data, key).getBytes();
    }

    /**
     * 加密
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static byte[] encryptToByte(String data, String key) {
        return encrypt(data.getBytes(), key);
    }

    /**
     * 加密
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static String encryptToStr(byte[] data, String key) {
        if (StringUtil.isNotBlankObject(key)) {
            data = EncryptUtil.keyEncrypt(data, key);
        }

        return encryptToStr(data);
    }

    /**
     * 加密并转为大写
     * 
     * @param data
     * @return
     */
    public static String encryptToUpperCase(String data) {
        return encrypt(data).toUpperCase();
    }

    /**
     * 加密并转为大写
     * 
     * @param data
     * @return
     */
    public static String encryptToUpperCase(byte[] data) {
        return encryptToStr(data).toUpperCase();
    }

    /**
     * 加密并转为大写
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static String encryptToUpperCase(String data, String key) {
        return encrypt(data, key).toUpperCase();
    }

    /**
     * 加密并转为大写
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static String encryptToUpperCase(byte[] data, String key) {
        return encryptToStr(data, key).toUpperCase();
    }

    /**
     * 获取MD5
     * 
     * @return
     */
    private static MessageDigest getMd5() {
        try {
            return MessageDigest.getInstance(EEncryptType.MD5.getType());
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

}